package com.dalin.platform.autocode;

import java.io.File;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import com.dalin.common.PropertyConst;
import com.dalin.common.clazz.ArgList;
import com.dalin.common.clazz.Clazz;
import com.dalin.common.clazz.ImportList;
import com.dalin.common.clazz.Interfazz;
import com.dalin.common.clazz.Method;
import com.dalin.common.clazz.Note;
import com.dalin.common.clazz.Property;
import com.dalin.common.clazz.PropertyList;
import com.dalin.common.utils.FileUtils;
import com.dalin.common.utils.NumberUtils;
import com.dalin.common.utils.StringUtils;
import com.dalin.common.utils.TextUtils;
import com.dalin.framework.dao.ConnectFactory;
import com.dalin.framework.dao.DbConn;
import com.dalin.framework.vos.ColumnBaseInfoVo;
import com.dalin.framework.vos.JdbcVo;

/*****************************************************************************
 * @content: autocode工程静态属性及类方法                                                                                        *
 * @author : 那建林                                                                                                                                 *
 * @crtDate: 2009-07-27                                                     *
 ****************************************************************************/
public final class AutocodeConst {
	private AutocodeConst() {}
	private static String NEXT_NJL_ID = "njlId27";
	public static String getNextNjlId() {
		return AutocodeConst.NEXT_NJL_ID = NumberUtils
				.getNextStrNum(AutocodeConst.NEXT_NJL_ID);
	}
	/*************************************************************************
	 * @content: 根据属性生成它的get/set方法
	 * @param  : propList 属性集合
	 * @return : List<Method>
	 * @author : 那建林
	 * @crtDate: 2009-09-17
	 * @modDate: 2010-05-11
	 * @version: 1.3 
	 */
	public static List<Method> getGetSetMethodList(PropertyList propList) {
		List<Method> methodList = new ArrayList<Method>();
		Method method = null;
		StringBuffer buf = null;
		for (Property p : propList.getAll()) {
			String pType = p.getType();
			String pName = p.getName();
			String upperPName = pName.substring(0, 1).toUpperCase()
					+ pName.substring(1);
			// getMethod
			buf = new StringBuffer();
			buf.append(PropertyConst.TAB).append(PropertyConst.TAB)
				.append(PropertyConst.RETURN_STR)
				.append(PropertyConst.SPACE).append(pName)
				.append(PropertyConst.SEMICOLON);
			method = new Method(PropertyConst.GET_STR + upperPName);
			method.setBody(buf.toString());
			method.setRtnType(pType);
			methodList.add(method);
			
			// setMethod
			buf = new StringBuffer();
			buf.append(PropertyConst.TAB).append(PropertyConst.TAB)
				.append(PropertyConst.THIS_STR).append(PropertyConst.DOT)
				.append(pName).append(PropertyConst.SPACE)
				.append(PropertyConst.EQUAL).append(PropertyConst.SPACE)
				.append(pName).append(PropertyConst.SEMICOLON);
			ArgList argList = new ArgList();
			argList.add(pType, pName);
			method = new Method(PropertyConst.SET_STR + upperPName);
			method.setArgList(argList);
			method.setBody(buf.toString());
			methodList.add(method);
		}
		return methodList;
	}
	
	
	/*************************************************************************
	 * @content: 根据表名生成普通的映射javabean,属性及相应的get/set方法
	 * @param  : jdbc 数据库连接bean
	 * @param  : tableName 表名
	 * @param  : packageName 包名
	 * @return : Clazz
	 * @author : 那建林                                   
	 * @crtDate: 2009-10-03 
	 * @modDate: 2010-05-11
	 * @version: 1.3 
	 * @throws Exception 
	 */
	public static Clazz getJavaClazz(
			DbConn conn, String tableName, String packageName) throws Exception {
		Set<ColumnBaseInfoVo> list = conn.queryColumnInfosByTable(tableName);
		PropertyList propList = new PropertyList();
		
		for (ColumnBaseInfoVo vo : list) {
			String lowerName = StringUtils
					.underlineToLowerCamelCase(vo.getColumnName());
			String javaType = conn.getJavaTypeFromColumnType(
									vo.getColumnType(),
									vo.getColumnLength(), 
									vo.getDecimalDigits());
			StringBuffer noteBuf = new StringBuffer();
			noteBuf.append(vo.getColumnName()).append(PropertyConst.COMMA)
					.append(vo.getColumnLength()).append(PropertyConst.COMMA)
					.append(vo.getDecimalDigits());
			propList.add(javaType, lowerName, noteBuf.toString());
		}

		Clazz myClass = new Clazz();
		myClass.setPackageName(packageName);
		myClass.setClassName(
				StringUtils.underlineToUpperCamelCase(tableName) + "Vo");
		myClass.setPropertyList(propList);
		myClass.setMethodList(getGetSetMethodList(propList));
		return myClass;
	}
	
	
	/*************************************************************************
	 * @content: 根据表名生成JPA注解映射bean
	 * @param  : jdbc 数据库连接bean
	 * @param  : tableName 表名
	 * @param  : packageName 包名
	 * @return : Clazz
	 * @author : 那建林                                   
	 * @crtDate: 2009-10-03 
	 * @modDate: 2010-05-11
	 * @version: 1.3 
	 * @throws Exception 
	 */
	public static Clazz getAnnotationClazz(
			DbConn conn, String tableName, String packageName) throws Exception {
		Clazz myClass = getJavaClazz(conn, tableName, packageName);
/*		ImportList importList = new ImportList();
		importList.add("java.io.Serializable")
				.add("javax.persistence.Column")
				.add("javax.persistence.Entity")
				.add("javax.persistence.GeneratedValue")
				.add("javax.persistence.GenerationType")
				.add("javax.persistence.Id")
				.add("javax.persistence.Table")
				.add("javax.persistence.TableGenerator");
		myClass.setImportList(importList);
		myClass.setNote("@Entity" + PropertyConst.LINE_SEPARATOR
				+ "@Table(name=\"" + tableName + "\")"
				+ PropertyConst.LINE_SEPARATOR);
		myClass.setExtendsClassName("com.dalin.framework.pager.CuteObject");*/
		
		PropertyList propList = myClass.getPropertyList();
		List<Method> methodList = myClass.getMethodList();
		int i = 0;
		for (Property p : propList.getAll()) {
			String[] noteArray = StringUtils
				.getStrArrayFromComma(p.getNote());
			String methodNote = Note.getHibernateAnnotation(
					noteArray[0], p.getType(), Integer.parseInt(noteArray[1]));
			if (i++ == 0) {
				/*StringBuffer buf = new StringBuffer();
				buf.append(PropertyConst.TAB).append("@Id").append(PropertyConst.LINE_SEPARATOR)
					.append(methodNote)
					.append(PropertyConst.TAB).append("@GeneratedValue(strategy = GenerationType.TABLE,generator=\"generator_normal\")").append(PropertyConst.LINE_SEPARATOR)
					.append(PropertyConst.TAB).append("@TableGenerator(").append(PropertyConst.LINE_SEPARATOR)
					.append(PropertyConst.TWO_TAB).append("name = \"generator_normal\",").append(PropertyConst.LINE_SEPARATOR)
					.append(PropertyConst.TWO_TAB).append("table = \"GLB_GENERATOR_KEY\",").append(PropertyConst.LINE_SEPARATOR)
					.append(PropertyConst.TWO_TAB).append("pkColumnName = \"GEN_KEY\",").append(PropertyConst.LINE_SEPARATOR)
					.append(PropertyConst.TWO_TAB).append("valueColumnName = \"GEN_VALUE\",").append(PropertyConst.LINE_SEPARATOR)
					.append(PropertyConst.TWO_TAB).append("pkColumnValue = \"" + tableName + "\",").append(PropertyConst.LINE_SEPARATOR)
					.append(PropertyConst.TWO_TAB).append("allocationSize=1").append(PropertyConst.LINE_SEPARATOR)
					.append(PropertyConst.TAB).append(")").append(PropertyConst.LINE_SEPARATOR);*/
				for (Method m : methodList) {
					if (m.getMethodName().equalsIgnoreCase(
							PropertyConst.GET_STR + p.getName())) {
						//m.setMethodNote(buf.toString());
						break;
					}
				}
				continue;
			}
			for (Method m : methodList) {
				if (m.getMethodName().equalsIgnoreCase(
						PropertyConst.GET_STR + p.getName())) {
					m.setMethodNote(methodNote);
					break;
				}
			}
		}
		myClass.setClassName(
				StringUtils.underlineToUpperCamelCase(tableName) + "Entity");
		return myClass;
	}
	
	
	/*************************************************************************
	 * @content: 根据表名生成condition查询封装类
	 * @param  : jdbc 数据库连接bean
	 * @param  : tableName 表名
	 * @param  : packageName 包名
	 * @return : Clazz
	 * @author : 那建林                                   
	 * @crtDate: 2009-10-03 
	 * @modDate: 2010-05-27
	 * @version: 1.3 
	 */
	public static Clazz getConditionClazz(DbConn conn,
			String tableName, String packageName) throws Exception {
		Clazz cls = getJavaClazz(conn, tableName, packageName);
		// 引用哪些包
		ImportList importList = new ImportList();
			importList.add("java.io.Serializable")
			.add("com.dalin.framework.pager.Condition")
			.add("com.dalin.common.utils.StringUtils")
			.add("com.dalin.common.utils.DateUtils");
		cls.setImportList(importList);
		
		//类名
		cls.setClassName(StringUtils.underlineToUpperCamelCase(tableName)
				+ "Condition");
		cls.setExtendsClassName("Condition");
		
		List<Method> methodList = cls.getMethodList();
		/**
		 * 增加 protected void prepareParams()方法
		 */ 
		Method preMethod = new Method("prepareParams");
		preMethod.setRtnType(cls.getClassName());
		StringBuffer bodyBuf = new StringBuffer(); // 方法体
		bodyBuf.append(PropertyConst.TWO_TAB)
			.append("setBaseQueryStr(\"from ")
			.append(StringUtils.underlineToUpperCamelCase(tableName)+"Entity")
			.append(" h\");").append(PropertyConst.LINE_SEPARATOR);
		PropertyList proList = cls.getPropertyList();
		PropertyList newPropList = new PropertyList();
		//先组织查询语句，再把类属性全变为String类型
		for (Property p : proList.getAll()) {
			String propType = p.getType();
			String propName = p.getName();
			if (PropertyConst.STRING_STR.equals(propType)) {
				bodyBuf.append(PropertyConst.TWO_TAB).append("setParam(\"h.")
					.append(propName).append("\", \"like\", \"%\" + ")
					.append(propName).append(" + \"%\");")
					.append(PropertyConst.LINE_SEPARATOR);
				newPropList.add(p);
			} else {
				bodyBuf.append(PropertyConst.TWO_TAB).append("setParam(\"h.")
					.append(propName).append("\", \">=\", ");
				if(PropertyConst.DOUBLE_STR.equals(propType)) {
					bodyBuf.append("StringUtils.getDoubleFromStrNum(");
				} else if (PropertyConst.DATE_STR.equals(propType)) {
					bodyBuf.append("DateUtils.getDate(");
				}
				bodyBuf.append(propName + 1)
					.append("));").append(PropertyConst.LINE_SEPARATOR);
				p.setName(propName + 1);
				newPropList.add(p);
				bodyBuf.append(PropertyConst.TWO_TAB).append("setParam(\"h.")
					.append(propName).append("\", \"<\", ");
				if(PropertyConst.DOUBLE_STR.equals(propType)) {
					bodyBuf.append("StringUtils.getDoubleFromStrNum(");
				} else if (PropertyConst.DATE_STR.equals(propType)) {
					bodyBuf.append("DateUtils.getDate(");
				}
				bodyBuf.append(propName + 2)
					.append("));").append(PropertyConst.LINE_SEPARATOR);
				p.setName(propName + 2);
				newPropList.add(p);
			}
		}
		cls.setPropertyList(newPropList);
		bodyBuf.append(PropertyConst.TWO_TAB).append("return this;");
		preMethod.setBody(bodyBuf.toString());
		methodList.add(preMethod);
		cls.setMethodList(methodList);
		return cls;
	}
	
	
	/*************************************************************************
	 * @content: 根据表名生成创建service接口类
	 * @param  : jdbc 数据库连接bean
	 * @param  : tableName 表名
	 * @param  : packageName 包名
	 * @return : Interfazz
	 * @author : 那建林                                   
	 * @crtDate: 2009-10-03 
	 * @modDate: 2010-05-30
	 * @version: 1.3 
	 */
	public static Interfazz getServiceInterfaceClazz(String tableName,
			String packageName) throws Exception {
		String javaTableName = StringUtils.underlineToUpperCamelCase(tableName);
		Interfazz inter = new Interfazz();
		inter.setInterfaceName(javaTableName + "Service");
		List<Method> methodList = new ArrayList<Method>();
		Method method = null;
		ArgList argList = new ArgList();
		/**
		 * 查询方法
		 */
		method = new Method("query" + javaTableName + "s");
		method.setRtnType("PageInfo");
		argList.add(javaTableName + "Condition", "cond");
		method.setArgList(argList);
		method.setMethodNote(Note.getMethodNote(method));
		method.setException("Exception");
		methodList.add(method);
		/**
		 * 查找单条记录方法
		 */
		method = new Method("find" + javaTableName + "ById");
		method.setRtnType(javaTableName + "Vo");
		argList = new ArgList();
		argList.add("Long", "id");
		method.setArgList(argList);
		method.setException("Exception");
		method.setMethodNote(Note.getMethodNote(method));
		methodList.add(method);
		/**
		 * 增加记录方法
		 */
		method = new Method("add" + javaTableName);
		argList = new ArgList();
		argList.add(javaTableName + "Vo", "vo");
		method.setArgList(argList);
		method.setException("Exception");
		method.setMethodNote(Note.getMethodNote(method));
		methodList.add(method);
		/**
		 * 修改记录方法
		 */
		method = new Method("modify" + javaTableName);
		argList = new ArgList();
		argList.add(javaTableName + "Vo", "vo");
		method.setArgList(argList);
		method.setException("Exception");
		method.setMethodNote(Note.getMethodNote(method));
		methodList.add(method);
		/**
		 * 删除方法
		 */
		method = new Method("del" + javaTableName + "sByIds");
		argList = new ArgList();
		argList.add("Long[]", "idArray");
		method.setArgList(argList);
		method.setException("Exception");
		method.setMethodNote(Note.getMethodNote(method));
		methodList.add(method);
		
		inter.setMethodList(methodList);
		return inter;
	}
	
	
	public static Clazz getServiceImpleClazz(DbConn conn, 
			String tableName, String packageName) throws Exception {
		String javaTableName = StringUtils.underlineToUpperCamelCase(tableName);
		PropertyList propList = getJavaClazz(conn, tableName, packageName)
				.getPropertyList();
		Interfazz inter = getServiceInterfaceClazz(tableName, packageName);
		Clazz cls = new Clazz();
		cls.setPackageName(packageName);
		cls.setClassName(inter.getInterfaceName() + "Imple");
		cls.setExtendsClassName("AbstractService");
		List<String> implementsList = new ArrayList<String>();
		implementsList.add(inter.getInterfaceName());
		cls.setImplementsList(implementsList);
		cls.setMethodList(inter.getMethodList());
		
		Method method = null;
		StringBuffer buf = null;
		/**
		 * 查询方法
		 */
		method = cls.getMethodList().get(0);
		method.setException("Exception");
		buf = new StringBuffer();
		buf.append(PropertyConst.TWO_TAB)
			.append("PageInfo pageInfo = queryPageInfoByCond(cond.prepareParams());")
			.append(PropertyConst.LINE_SEPARATOR).append(PropertyConst.TWO_TAB)
			.append("List<").append(javaTableName).append("Entity")
			.append("> entyList = pageInfo.getDataList();")
			.append(PropertyConst.LINE_SEPARATOR).append(PropertyConst.TWO_TAB)
			.append("List<").append(javaTableName)
			.append("Vo> voList = new ArrayList<")
			.append(javaTableName).append("Vo>();")
			.append(PropertyConst.LINE_SEPARATOR).append(PropertyConst.TWO_TAB)
			.append(javaTableName).append("Vo vo = null;")
			.append(PropertyConst.LINE_SEPARATOR).append(PropertyConst.TWO_TAB);
		//for循环
		buf.append("for (").append(javaTableName)
			.append("Entity enty : entyList) {").append(PropertyConst.LINE_SEPARATOR);
		buf.append(PropertyConst.THREE_TAB).append("vo = new ")
			.append(javaTableName).append("Vo();")
			.append(PropertyConst.LINE_SEPARATOR);
		buf.append(setPropertyValue(propList, "vo", "enty"));
		buf.append(PropertyConst.TWO_TAB).append("voList.add(vo);")
			.append(PropertyConst.LINE_SEPARATOR);
		buf.append(PropertyConst.TWO_TAB)
			.append(PropertyConst.RIGHT_BRACE).append(PropertyConst.LINE_SEPARATOR);
		buf.append(PropertyConst.TWO_TAB).append("pageInfo.setDataList(voList);")
			.append(PropertyConst.LINE_SEPARATOR).append(PropertyConst.TWO_TAB)
			.append("return pageInfo;");
		method.setBody(buf.toString());
		cls.getMethodList().set(0, method);
		/**
		 * 查找单条记录方法
		 */
		method = cls.getMethodList().get(1);
		method.setException("Exception");
		buf = new StringBuffer();
		buf.append(PropertyConst.TWO_TAB).append(javaTableName + "Entity")
			.append(" enty = (").append(javaTableName + "Entity")
			.append(") getDao().findObjById(")
			.append(javaTableName + "Entity.class, id);")
			.append(PropertyConst.LINE_SEPARATOR);
		buf.append(PropertyConst.TWO_TAB).append(javaTableName + "Vo")
			.append(" vo = new ").append(javaTableName)
			.append("Vo();").append(PropertyConst.LINE_SEPARATOR);
		buf.append(setPropertyValue(propList, "vo", "enty"));
		buf.append(PropertyConst.TWO_TAB).append("return vo;");
		method.setBody(buf.toString());
		cls.getMethodList().set(1, method);
		/**
		 * 增加记录方法
		 */
		method = cls.getMethodList().get(2);
		buf = new StringBuffer();
		buf.append(PropertyConst.TWO_TAB).append(javaTableName + "Entity")
			.append(" enty = new ").append(javaTableName + "Entity();")
			.append(PropertyConst.LINE_SEPARATOR);
		buf.append(PropertyConst.TWO_TAB).append("enty = get")
			.append(javaTableName).append("EntityValue(enty, vo);")
			.append(PropertyConst.LINE_SEPARATOR);
		buf.append(PropertyConst.TWO_TAB).append("getDao().createObj(enty);");
		method.setBody(buf.toString());
		cls.getMethodList().set(2, method);
		/**
		 * 修改记录方法
		 */
		method = cls.getMethodList().get(3);
		method.setException("Exception");
		buf = new StringBuffer();
		buf.append(PropertyConst.TWO_TAB).append("Long id = vo.get")
			.append(javaTableName + "Id();").append(PropertyConst.LINE_SEPARATOR);
		buf.append(PropertyConst.TWO_TAB).append(javaTableName + "Entity")
			.append(" enty = (").append(javaTableName + "Entity")
			.append(") getDao().findObjById(")
			.append(javaTableName + "Entity.class, id);")
			.append(PropertyConst.LINE_SEPARATOR);
		buf.append(PropertyConst.TWO_TAB).append("enty = get")
			.append(javaTableName).append("EntityValue(enty, vo);")
			.append(PropertyConst.LINE_SEPARATOR);
		buf.append(PropertyConst.TWO_TAB).append("getDao().updateObj(enty);");
		method.setBody(buf.toString());
		cls.getMethodList().set(3, method);
		/**
		 * 批量删除方法
		 */
		method = cls.getMethodList().get(4);
		method.setException("Exception");
		buf = new StringBuffer();
		buf.append(PropertyConst.TWO_TAB).append("getDao().deleteObjs(")
			.append(javaTableName).append("Entity.class, idArray);");
		method.setBody(buf.toString());
		cls.getMethodList().set(4, method);
		/**
		 * 增加属性值copy方法
		 */
		method = new Method("get" + javaTableName + "EntityValue");
		method.setModifier(PropertyConst.PRIVATE_STR);
		method.setRtnType(javaTableName + "Entity");
		ArgList argList = new ArgList();
		argList.add(javaTableName + "Entity", "enty");
		argList.add(javaTableName + "Vo", "vo");
		method.setArgList(argList);
		method.setBody(setPropertyValue(propList, "enty", "vo"));
		cls.getMethodList().add(method);
		return cls;
	}

	
	public static Clazz getAddModActionClazz(String serviceName, String tableName,
			String packageName) throws Exception {
		String serviceRefName = serviceName.substring(0, 1).toLowerCase() 
				+ serviceName.substring(1);
		String upperJavaName = StringUtils.underlineToUpperCamelCase(tableName);
		PropertyList propertyList = new PropertyList();
		propertyList.add(new Property(serviceName, serviceRefName, null));
		propertyList.add(new Property(upperJavaName + "Vo", "vo", null));
		List<Method> methodList = new ArrayList<Method>();
		Method method = new Method("execute");
		method.setRtnType(PropertyConst.STRING_STR);
		method.setException("Exception");
		StringBuffer buf = new StringBuffer();
		buf.append(PropertyConst.TWO_TAB)
			.append("super.printInfo(\"\", \"===== this action begin\");")
			.append(PropertyConst.LINE_SEPARATOR);
		buf.append(PropertyConst.TWO_TAB).append("if (vo.get")
			.append(upperJavaName).append("Id() == null) {")
			.append(PropertyConst.LINE_SEPARATOR);
		buf.append(PropertyConst.THREE_TAB).append(serviceRefName)
			.append(".add").append(upperJavaName)
			.append("(vo);").append(PropertyConst.LINE_SEPARATOR);
		buf.append(PropertyConst.TWO_TAB).append("} else {")
			.append(PropertyConst.LINE_SEPARATOR);
		buf.append(PropertyConst.THREE_TAB).append(serviceRefName)
			.append(".modify").append(upperJavaName)
			.append("(vo);").append(PropertyConst.LINE_SEPARATOR);
		buf.append(PropertyConst.TWO_TAB).append("}")
			.append(PropertyConst.LINE_SEPARATOR);
		buf.append(PropertyConst.TWO_TAB)
			.append("setResContent(\"{success: true, info: ''}\");")
			.append(PropertyConst.LINE_SEPARATOR);
		buf.append(PropertyConst.TWO_TAB)
			.append("return null;")
			.append(PropertyConst.LINE_SEPARATOR);
		buf.append(PropertyConst.TWO_TAB)
			.append("super.printInfo(\"\", \"===== this action end\");")
			.append(PropertyConst.LINE_SEPARATOR);
		method.setBody(buf.toString());
		methodList.add(method);
		List<Method> getSetMethodList = buildGetSetMethodByProperty(
				propertyList);
		for (Method m : getSetMethodList) {
			methodList.add(m);
		}
		
		Clazz cls = new Clazz();
		cls.setPackageName(packageName);
		ImportList importList = new ImportList();
		importList.add("com.dalin.framework.action.StrutsTwoAction");
		cls.setImportList(importList);
		cls.setClassName(upperJavaName + "AddModAction");
		cls.setExtendsClassName("StrutsTwoAction");
		cls.setPropertyList(propertyList);
		cls.setMethodList(methodList);
		return cls;
	}
	
	
	public static Clazz getDelActionClazz(String serviceName, String tableName,
			String packageName) throws Exception {
		String serviceRefName = serviceName.substring(0, 1).toLowerCase() 
				+ serviceName.substring(1);
		String upperJavaName = StringUtils.underlineToUpperCamelCase(tableName);
		PropertyList propertyList = new PropertyList();
		propertyList.add(new Property(serviceName, serviceRefName, null));
		propertyList.add(new Property("Long[]", "idArray", null));
		List<Method> methodList = new ArrayList<Method>();
		Method method = new Method("execute");
		method.setRtnType(PropertyConst.STRING_STR);
		method.setException("Exception");
		StringBuffer buf = new StringBuffer();
		buf.append(PropertyConst.TWO_TAB)
			.append("super.printInfo(\"\", \"===== this action begin\");")
			.append(PropertyConst.LINE_SEPARATOR);
		buf.append(PropertyConst.TWO_TAB).append(serviceRefName)
			.append(".del").append(upperJavaName)
			.append("sByIds(ids);").append(PropertyConst.LINE_SEPARATOR);
		buf.append(PropertyConst.TWO_TAB)
			.append("super.printInfo(\"\", \"===== this action begin\");")
			.append(PropertyConst.LINE_SEPARATOR);
		buf.append(PropertyConst.TWO_TAB)
			.append("return null;")
			.append(PropertyConst.LINE_SEPARATOR);
		method.setBody(buf.toString());
		methodList.add(method);
		List<Method> getSetMethodList = buildGetSetMethodByProperty(propertyList);
		for (Method m : getSetMethodList) {
			methodList.add(m);
		}
		
		Clazz cls = new Clazz();
		cls.setPackageName(packageName);
		ImportList importList = new ImportList();
		importList.add("com.dalin.framework.action.StrutsTwoAction");
		cls.setImportList(importList);
		cls.setClassName(upperJavaName + "DelAction");
		cls.setExtendsClassName("StrutsTwoAction");
		cls.setPropertyList(propertyList);
		cls.setMethodList(methodList);
		return cls;
	}

	
	public static Clazz getFindActionClazz(String serviceName, String tableName,
			String packageName) throws Exception {
		String serviceRefName = serviceName.substring(0, 1).toLowerCase() 
				+ serviceName.substring(1);
		String upperJavaName = StringUtils.underlineToUpperCamelCase(tableName);
		PropertyList propertyList = new PropertyList();
		propertyList.add(new Property(serviceName, serviceRefName, null));
		propertyList.add(new Property("Long", "id", null));
		List<Method> methodList = new ArrayList<Method>();
		Method method = new Method("execute");
		method.setRtnType(PropertyConst.STRING_STR);
		method.setException("Exception");
		StringBuffer buf = new StringBuffer();
		buf.append(PropertyConst.TWO_TAB)
		.append("super.printInfo(\"\", \"===== this action begin\");")
		.append(PropertyConst.LINE_SEPARATOR);
		buf.append(PropertyConst.TWO_TAB).append(upperJavaName)
			.append("Vo vo = ").append(serviceRefName)
			.append(".find").append(upperJavaName)
			.append("ById(id);").append(PropertyConst.LINE_SEPARATOR);
		buf.append(PropertyConst.TWO_TAB)
			.append("setResContent(vo, \"data\");")
			.append(PropertyConst.LINE_SEPARATOR);
		buf.append(PropertyConst.TWO_TAB)
			.append("return null;")
			.append(PropertyConst.LINE_SEPARATOR);
		buf.append(PropertyConst.TWO_TAB)
		.append("super.printInfo(\"\", \"===== this action end\");")
		.append(PropertyConst.LINE_SEPARATOR);
		method.setBody(buf.toString());
		methodList.add(method);
		
		methodList.addAll(buildGetSetMethodByProperty(propertyList));
		
		Clazz cls = new Clazz();
		cls.setPackageName(packageName);
		ImportList importList = new ImportList();
		importList.add("com.dalin.framework.action.StrutsTwoAction");
		cls.setImportList(importList);
		cls.setClassName(upperJavaName + "FindAction");
		cls.setExtendsClassName("StrutsTwoAction");
		cls.setPropertyList(propertyList);
		cls.setMethodList(methodList);
		return cls;
	}
	
	
	public static Clazz getQueryActionClazz(String serviceName, String tableName,
			String packageName) throws Exception {
		String serviceRefName = serviceName.substring(0, 1).toLowerCase() 
				+ serviceName.substring(1);
		String upperJavaName = StringUtils.underlineToUpperCamelCase(tableName);
		PropertyList propertyList = new PropertyList();
		propertyList.add(new Property(serviceName, serviceRefName, null));
		propertyList.add(new Property("String", "condStr", "查询条件"));
		propertyList.add(new Property("int", "start", "查询起始行数"));
		propertyList.add(new Property("int", "limit", "每页显示行数"));
		List<Method> methodList = new ArrayList<Method>();
		Method method = new Method("execute");
		method.setRtnType(PropertyConst.STRING_STR);
		method.setException("Exception");
		StringBuffer buf = new StringBuffer();
		buf.append(PropertyConst.TWO_TAB)
		.append("super.printInfo(\"\", \"===== this action begin\");")
		.append(PropertyConst.LINE_SEPARATOR);
		buf.append(PropertyConst.TWO_TAB).append(upperJavaName)
			.append("Condition cond = new ").append(upperJavaName)
			.append("Condition(start, limit);").append(PropertyConst.LINE_SEPARATOR);
		buf.append(PropertyConst.TWO_TAB).append("cond = (")
			.append(upperJavaName)
			.append("Condition) getConditionValue(cond, condStr);")
			.append(PropertyConst.LINE_SEPARATOR);
		buf.append(PropertyConst.TWO_TAB).append("PageInfo pageInfo = ")
			.append(serviceRefName).append(".query").append(upperJavaName)
			.append("s(cond);").append(PropertyConst.LINE_SEPARATOR);
		buf.append(PropertyConst.TWO_TAB)
			.append("setResContent(pageInfo);")
			.append(PropertyConst.LINE_SEPARATOR);
		buf.append(PropertyConst.TWO_TAB)
			.append("return null;")
			.append(PropertyConst.LINE_SEPARATOR);
		buf.append(PropertyConst.TWO_TAB)
		.append("super.printInfo(\"\", \"===== this action end\");")
		.append(PropertyConst.LINE_SEPARATOR);
		method.setBody(buf.toString());
		methodList.add(method);
		
		methodList.addAll(buildGetSetMethodByProperty(propertyList));
		
		Clazz cls = new Clazz();
		cls.setPackageName(packageName);
		ImportList importList = new ImportList();
		importList.add("com.dalin.framework.action.StrutsTwoAction");
		cls.setImportList(importList);
		cls.setClassName(upperJavaName + "QueryAction");
		cls.setExtendsClassName("StrutsTwoAction");
		cls.setPropertyList(propertyList);
		cls.setMethodList(methodList);
		return cls;
	}
	
	
	// 增删查改
	public static void crudAndExts(DbConn conn,
			String tableName, String packageName) throws Exception {
		String savedDir = "/tmp/crud/"+ tableName + "/";
		File f = new File(savedDir);
		FileUtils.deleteFiles(f);
		f.mkdirs();

		// VO值对象
		Clazz myClazz = getJavaClazz(conn, tableName, packageName);
		TextUtils.overwriteToText(myClazz.toString(),
				new File(savedDir + myClazz.getClassName() + ".java"));
		// Annotation值对象
		myClazz = getAnnotationClazz(conn, tableName, packageName+".models");
		TextUtils.overwriteToText(myClazz.toString(),
				new File(savedDir + myClazz.getClassName() + ".java"));
		
		// Condition查询条件对象
		myClazz = getConditionClazz(conn, tableName, packageName);
		TextUtils.overwriteToText(myClazz.toString(),
				new File(savedDir + myClazz.getClassName() + ".java"));
		
		// service接口类
		Interfazz fazz = getServiceInterfaceClazz(tableName, packageName);
		TextUtils.overwriteToText(fazz.toString(),
				new File(savedDir + fazz.getInterfaceName() + ".java"));
		
		// service接口实现类
		myClazz = getServiceImpleClazz(conn, tableName, packageName);
		TextUtils.overwriteToText(myClazz.toString(),
				new File(savedDir + myClazz.getClassName() + ".java"));
		
		// 增加修改action类
		myClazz = getAddModActionClazz(
				"LoaService", tableName, packageName);
		TextUtils.overwriteToText(myClazz.toString(), 
				new File(savedDir + myClazz.getClassName() + ".java"));
		
		// 删除功能action类
		myClazz = getDelActionClazz("LoaService", tableName, packageName);
		TextUtils.overwriteToText(myClazz.toString(),
				new File(savedDir + myClazz.getClassName() + ".java"));
	
		// 查找操作的action类
		myClazz = getFindActionClazz("LoaService", tableName, packageName);
		TextUtils.overwriteToText(myClazz.toString(),
				new File(savedDir + myClazz.getClassName() + ".java"));
		
		// 查询列表操作的action类
		myClazz = getQueryActionClazz("LoaService", tableName, packageName);
		TextUtils.overwriteToText(myClazz.toString(),
				new File(savedDir + myClazz.getClassName() + ".java"));
//		
//		// EXT
//		myClazz = buildExtTextFieldComponent(tableName).toString();
//		TextUtils.overwriteToText(myClazz, savedPath + "Textfield.js");
	}
	

	//把一个类的属性赋给另一个类的属性
	public static String setPropertyValue(PropertyList propList,
			String setRef, String getRef) {
		StringBuffer buf = new StringBuffer();
		for (Property p : propList.getAll()) {
			String pName = p.getName();
			pName = pName.substring(0, 1).toUpperCase() + pName.substring(1);
			buf.append(PropertyConst.TWO_TAB).append(setRef)
				.append(".set").append(pName).append("(").append(getRef)
				.append(".get").append(pName).append("()); // ")
				.append(PropertyConst.LINE_SEPARATOR);
		}
		return buf.toString();
	}
	
	/*************************************************************************
	 * @content: 根据属性生成它的get/set方法
	 * @param  : propList 属性集合
	 * @return : List<Method>
	 * @author : 那建林
	 * @crtDate: 2009-09-17
	 */
	public static List<Method> buildGetSetMethodByProperty(
			PropertyList propList) {
		List<Method> methodList = new ArrayList<Method>();
		Method method = null;
		StringBuffer buf = null;
		for (Property p : propList.getAll()) {
			String pType = p.getType();
			String pName = p.getName();
			String upperPName = pName.substring(0, 1).toUpperCase()
					+ pName.substring(1);
			// getMethod
			buf = new StringBuffer();
			buf.append(PropertyConst.TAB).append(PropertyConst.TAB)
				.append(PropertyConst.RETURN_STR)
				.append(PropertyConst.SPACE).append(pName)
				.append(PropertyConst.SEMICOLON).append(PropertyConst.LINE_SEPARATOR);
			method = new Method(PropertyConst.GET_STR + upperPName);
			method.setBody(buf.toString());
			method.setRtnType(pType);
			methodList.add(method);
			
			// setMethod
			buf = new StringBuffer();
			buf.append(PropertyConst.TAB).append(PropertyConst.TAB)
				.append(PropertyConst.THIS_STR).append(PropertyConst.DOT)
				.append(pName).append(PropertyConst.SPACE)
				.append(PropertyConst.EQUAL).append(PropertyConst.SPACE)
				.append(pName).append(PropertyConst.SEMICOLON)
				.append(PropertyConst.LINE_SEPARATOR);
			ArgList argList = new ArgList();
			argList.add(pType, pName);
			method = new Method(PropertyConst.SET_STR + upperPName);
			method.setArgList(argList);
			method.setBody(buf.toString());
			methodList.add(method);
		}
		return methodList;
	}
	
	public static Method computeHashCode(Class c) throws Exception {
		StringBuffer body = new StringBuffer();
		body.append(PropertyConst.TWO_TAB).append("int njlrst = 17;")
			.append(PropertyConst.LINE_SEPARATOR);
		for (Field d : c.getDeclaredFields()) {
			body.append(PropertyConst.TWO_TAB).append("njlrst = 31 * njlrst + (")
				.append(d.getName()).append(" == null ? 0 : ")
				.append(d.getName()).append(".hashCode());")
			.append(PropertyConst.LINE_SEPARATOR);
		}
		body.append(PropertyConst.TWO_TAB).append("return njlrst;");
		Method rtnMethod = new Method("hashCode");
		rtnMethod.setMethodNote("@Override");
		rtnMethod.setBody(body.toString());
		rtnMethod.setRtnType("int");
		return rtnMethod;
	}
	
	
	public static Method computeEquals(Class c) throws Exception {
		StringBuffer body = new StringBuffer();
		body.append(PropertyConst.TWO_TAB).append("if (this == o) return true;")
			.append(PropertyConst.LINE_SEPARATOR)
			.append(PropertyConst.TWO_TAB).append("if (!(o instanceof ")
			.append(c.getSimpleName()).append(")) return false;")
			.append(PropertyConst.LINE_SEPARATOR)
			.append(PropertyConst.TWO_TAB).append("final ")
			.append(c.getSimpleName()).append(" other = (")
			.append(c.getSimpleName()).append(") o;")
			.append(PropertyConst.LINE_SEPARATOR);
		for (Field d : c.getDeclaredFields()) {
			body.append(PropertyConst.TWO_TAB).append("if (")
				.append(d.getName()).append(" == null) {")
				.append(PropertyConst.LINE_SEPARATOR)
				.append(PropertyConst.THREE_TAB).append("if (other.")
				.append(d.getName()).append(" != null) return false;")
				.append(PropertyConst.LINE_SEPARATOR)
			
				.append(PropertyConst.TWO_TAB).append("} else if (!")
				.append(d.getName()).append(".equals(other.").append(d.getName())
				.append(")) {").append(PropertyConst.LINE_SEPARATOR)
				.append(PropertyConst.THREE_TAB).append("return false;")
				.append(PropertyConst.LINE_SEPARATOR)
				.append(PropertyConst.TWO_TAB).append("}")
				.append(PropertyConst.LINE_SEPARATOR);
		}
		body.append(PropertyConst.TWO_TAB).append("return true;");
		Method rtnMethod = new Method("equals");
		rtnMethod.setMethodNote("@Override");
		rtnMethod.setArgList(new ArgList().add("Object", "o"));
		rtnMethod.setBody(body.toString());
		rtnMethod.setRtnType("boolean");
		return rtnMethod;
	}

	
	public static void buildSkyFormMybatisCode() {
		JdbcVo jdbc = new JdbcVo();
		jdbc.setDriverClassName(PropertyConst.DRIVER_MYSQL);
		jdbc.setHostIp("10.10.182.33");          // 主机IP
		jdbc.setPort("3306");            // 端口号
		jdbc.setDbName("skyform_pxe");      // 数据库名
		jdbc.setUserName("skycloud");        // 用户名
		jdbc.setUserPswd("skycloud");        // 密码
		DbConn conn;
		try {
			conn = ConnectFactory.getConnectionInstance(jdbc);
			Set<String> tts = conn.queryTables();
			for (String s : tts) {
				buildSkyFormMybatisCode1(conn, s.toLowerCase());
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}	
	public static void buildSkyFormMybatisCode1(DbConn conn, String tableName) {
//		String tableName = "T_SCS_MAIL_DUTY";
		String key = "ID";
		String keyc = "id";
		String ucc = StringUtils.underlineToUpperCamelCase(tableName);
		try {
			crudAndExts(conn, tableName, "com.skyform.core.entity");
			
			StringBuffer sb = new StringBuffer("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
			sb.append("<!DOCTYPE mapper  \n");
			sb.append("PUBLIC \"-//ibatis.apache.org//DTD Mapper 3.0//EN\"  \n");
			sb.append("\"http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd\">\n");
			sb.append("<mapper namespace=\""+ucc+"Entity\">\n");
			sb.append("<select id=\"selectList\" parameterType=\"com.skyform.core.condition."+ucc+"Cond\" resultType=\"com.skyform.core.entity."+ucc+"Entity\">\n");
			sb.append("    select\n");
			Set<ColumnBaseInfoVo> cs = conn.queryColumnInfosByTable(tableName); 
			int i = 0;
			for (ColumnBaseInfoVo ci : cs) {
				System.out.print(ci.getColumnName()+", ");
				sb.append("        t."+ci.getColumnName()+" as "+StringUtils.underlineToLowerCamelCase(ci.getColumnName()));
				if (++i == cs.size()) {
					sb.append("\n");
				} else {
					sb.append(", \n");
				}
			}
			sb.append("    from "+tableName+" t where 1=1\n");
			sb.append("</select>\n");
			sb.append("<delete id=\"delete\" parameterType=\"java.lang.Integer\">\n");
			sb.append("    delete from "+tableName+" where "+key+"=#{"+keyc+"}\n");
			sb.append("</delete>\n<insert id=\"insert\" parameterType=\"com.skyform.core.entity."+ucc+"Entity\">\n");
			sb.append("    insert into "+tableName+"(\n");
			i = 0;
			for (ColumnBaseInfoVo ci : cs) {
				sb.append("        "+ci.getColumnName());
				if (++i == cs.size()) {
					sb.append("\n");
				} else {
					sb.append(", \n");
				}
			}
			sb.append("    ) values (\n");
			i = 0;
			for (ColumnBaseInfoVo ci : cs) {
				sb.append("        #{"+StringUtils.underlineToLowerCamelCase(ci.getColumnName())+"}");
				if (++i == cs.size()) {
					sb.append("\n");
				} else {
					sb.append(", \n");
				}
			}
			sb.append("    )\n");
			sb.append("</insert>\n<update id=\"update\" parameterType=\"com.skyform.core.entity."+ucc+"Entity\">\n");
			sb.append("    update "+tableName+" \n");
			sb.append("		<set>\n");
			i = 0;
			for (ColumnBaseInfoVo ci : cs) {
				sb.append("			<if test=\""+StringUtils.underlineToLowerCamelCase(ci.getColumnName())+" != null\">"+ci.getColumnName()+" = #{"+StringUtils.underlineToLowerCamelCase(ci.getColumnName())+"}");
				if (++i == cs.size()) {
					sb.append("</if>\n\n");
				} else {
					sb.append(",</if>\n");
				}
			}
			sb.append("		</set>\n");
			sb.append("		where "+key+" = #{"+keyc+"}\n");
			sb.append("</update>\n</mapper>\n");
			TextUtils.overwriteToText(sb.toString(), new File("/tmp/crud/"+ucc+"Entity.xml"));
			System.out.println(tableName);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public static void compareTwoTables() {
		JdbcVo jdbc = new JdbcVo();
		jdbc.setDriverClassName(PropertyConst.DRIVER_MYSQL);
		jdbc.setHostIp("192.168.31.124");          // 主机IP
		jdbc.setPort("3306");            // 端口号
		jdbc.setDbName("skycloud");      // 数据库名
		jdbc.setUserName("skycloud");        // 用户名
		jdbc.setUserPswd("skycloud");        // 密码
	
		JdbcVo jdbc2 = new JdbcVo();
		jdbc2.setDriverClassName(PropertyConst.DRIVER_MYSQL);
		jdbc2.setHostIp("localhost");          // 主机IP
		jdbc2.setPort("3306");            // 端口号
		jdbc2.setDbName("skycloudgdvdc");      // 数据库名
		jdbc2.setUserName("skycloud");        // 用户名
		jdbc2.setUserPswd("skycloud");        // 密码
		
		try {
			DbConn conn = ConnectFactory.getConnectionInstance(jdbc);
			Set<String> set = conn.queryTables();
			DbConn conn2 = ConnectFactory.getConnectionInstance(jdbc2);
			Set<String> set2 = conn2.queryTables();
			for (String name : set) {
				if (!set2.contains(name)) {
					System.out.println("无此表:" + name);
					continue;
				}
				Set<ColumnBaseInfoVo> cs = conn.queryColumnInfosByTable(name);
				Set<ColumnBaseInfoVo> cs2 = conn2.queryColumnInfosByTable(name);
				for (ColumnBaseInfoVo ci : cs) {
					if (!cs2.contains(ci)) {
						System.out.println("       表[" + name + "]中无字段:" + ci.getColumnName());
					} else {
						for (ColumnBaseInfoVo ci2 : cs2) {
							if (ci2.getColumnName().equals(ci.getColumnName())) {
								if (!ci2.getColumnType().equals(ci.getColumnType())) {
									System.out.println("       表[" + name + "]中字段["+ci.getColumnName()+"]类型不同, 应为:" + ci.getColumnType());
								} else if (ci2.getColumnLength() != ci.getColumnLength()) {
									System.out.println("       表[" + name + "]中字段["+ci.getColumnName()+"]长度不同, 应为:" + ci.getColumnLength());
								}
							}
						}
					}
				}
			}
			System.out.println("over");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) {
		buildSkyFormMybatisCode();
	}
}